import 'package:flutter/material.dart';
import 'package:photo_view/photo_view.dart';
import 'package:photo_view/photo_view_gallery.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:http/http.dart' as http;
import 'dart:async';
import 'dart:developer' as developer;
import '../../services/file_service.dart';
import 'minio_image_provider.dart';

/// 增强版图片预览组件
/// 支持MinIO私有桶的token刷新逻辑，并结合photo_view实现
class EnhancedImagePreview extends StatefulWidget {
  final String? previewUrl;
  final String? fileName;
  final int fileId;
  final VoidCallback? onRetry;

  const EnhancedImagePreview({
    Key? key,
    required this.previewUrl,
    required this.fileId,
    this.fileName,
    this.onRetry,
  }) : super(key: key);

  @override
  State<EnhancedImagePreview> createState() => _EnhancedImagePreviewState();
}

class _EnhancedImagePreviewState extends State<EnhancedImagePreview> {
  String? _currentUrl;
  bool _isLoading = true;
  bool _hasError = false;
  String? _errorMessage;
  bool _isTokenRefreshing = false;
  Timer? _tokenRefreshTimer;
  final int _tokenRefreshInterval = 10; // 分钟
  bool _useDirectImage = false; // 是否使用直接Image组件而不是PhotoView

  @override
  void initState() {
    super.initState();
    _currentUrl = widget.previewUrl;
    developer.log('初始化图片预览，URL: $_currentUrl', name: 'EnhancedImagePreview');
    _checkImageAvailability();
    // 设置定时刷新token
    _setupTokenRefreshTimer();
  }

  @override
  void dispose() {
    _tokenRefreshTimer?.cancel();
    super.dispose();
  }

  /// 设置定时刷新token的计时器
  void _setupTokenRefreshTimer() {
    // 每隔一定时间自动刷新token，避免过期
    _tokenRefreshTimer = Timer.periodic(
      Duration(minutes: _tokenRefreshInterval),
      (timer) {
        // 仅在组件仍然挂载时刷新
        if (mounted) {
          _refreshImageToken();
        }
      },
    );
  }

  /// 检查图片URL是否可访问
  Future<void> _checkImageAvailability() async {
    if (_currentUrl == null) {
      setState(() {
        _isLoading = false;
        _hasError = true;
        _errorMessage = '无效的图片地址';
      });
      developer.log('图片URL为空', name: 'EnhancedImagePreview');
      return;
    }

    setState(() {
      _isLoading = true;
      _hasError = false;
      _errorMessage = null;
    });

    try {
      developer.log('图片URL: $_currentUrl', name: 'EnhancedImagePreview');

      // 直接设置为非加载状态，让图片组件自己处理加载
      setState(() {
        _isLoading = false;
      });
    } catch (e) {
      developer.log('检查图片时出错: $e', name: 'EnhancedImagePreview');
      setState(() {
        _isLoading = false;
      });
    }
  }

  /// 刷新图片token
  Future<void> _refreshImageToken() async {
    if (_isTokenRefreshing) return; // 防止重复刷新

    setState(() {
      _isTokenRefreshing = true;
      if (_isLoading == false) {
        // 如果不是初始加载，显示刷新状态
        _isLoading = true;
      }
    });

    try {
      developer.log('开始刷新图片token', name: 'EnhancedImagePreview');

      // 从服务获取新的预览URL
      final preview = await FileService.getFilePreview(
        widget.fileId,
        forceRefresh: true,
      );

      if (preview.data?.url != null && preview.data!.url.isNotEmpty) {
        setState(() {
          _currentUrl = preview.data!.url;
          _isLoading = false;
          _hasError = false;
          _errorMessage = null;
        });
        developer.log('成功刷新图片URL: $_currentUrl', name: 'EnhancedImagePreview');
      } else {
        throw Exception('刷新图片地址失败：服务器返回空地址');
      }
    } catch (e, stack) {
      developer.log(
        '刷新图片token时出错:\n'
        '错误: $e\n'
        '堆栈: $stack',
        name: 'EnhancedImagePreview',
      );
      if (mounted) {
        setState(() {
          _isLoading = false;
          _hasError = true;
          _errorMessage = '刷新授权失败: ${e.toString()}';
        });
      }
    } finally {
      if (mounted) {
        setState(() {
          _isTokenRefreshing = false;
        });
      }
    }
  }

  /// 切换图片显示模式
  void _toggleImageMode() {
    setState(() {
      _useDirectImage = !_useDirectImage;
    });
    developer.log(
      '切换图片显示模式: ${_useDirectImage ? "直接Image" : "PhotoView"}',
      name: 'EnhancedImagePreview',
    );
  }

  @override
  Widget build(BuildContext context) {
    if (_isLoading) {
      return const Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            CircularProgressIndicator(),
            SizedBox(height: 16),
            Text('图片加载中...'),
          ],
        ),
      );
    }

    if (_hasError) {
      return _buildErrorWidget(context);
    }

    return _useDirectImage
        ? _buildDirectImageView(context)
        : _buildPhotoViewGallery(context);
  }

  /// 构建直接图片视图
  Widget _buildDirectImageView(BuildContext context) {
    return Stack(
      children: [
        Center(
          child: InteractiveViewer(
            minScale: 0.5,
            maxScale: 3.0,
            child: Image(
              image: MinioImageProvider(
                _currentUrl!,
                headers: {'Accept': 'image/jpeg,image/png,image/*,*/*;q=0.8'},
              ),
              loadingBuilder: (context, child, loadingProgress) {
                if (loadingProgress == null) return child;
                return Center(
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      CircularProgressIndicator(
                        value:
                            loadingProgress.expectedTotalBytes != null
                                ? loadingProgress.cumulativeBytesLoaded /
                                    loadingProgress.expectedTotalBytes!
                                : null,
                      ),
                      const SizedBox(height: 16),
                      Text(
                        '加载中: ${((loadingProgress.cumulativeBytesLoaded / (loadingProgress.expectedTotalBytes ?? 1)) * 100).toStringAsFixed(1)}%',
                      ),
                      const SizedBox(height: 8),
                      Text(
                        '已加载: ${_formatBytes(loadingProgress.cumulativeBytesLoaded)}',
                        style: const TextStyle(fontSize: 12),
                      ),
                    ],
                  ),
                );
              },
              errorBuilder: (context, error, stackTrace) {
                developer.log(
                  '图片加载错误:\n'
                  '错误: $error\n'
                  '堆栈: $stackTrace\n'
                  'URL: $_currentUrl',
                  name: 'EnhancedImagePreview',
                );

                // 如果错误信息包含特定关键字，自动尝试刷新token
                if (error.toString().contains('403') ||
                    error.toString().contains('授权已过期') ||
                    error.toString().contains('访问被拒绝')) {
                  // 延迟一下再刷新，避免刷新太频繁
                  Future.delayed(const Duration(milliseconds: 100), () {
                    if (mounted) {
                      _refreshImageToken();
                    }
                  });
                }

                setState(() {
                  _hasError = true;
                  _errorMessage = error.toString();
                });
                return _buildErrorWidget(context);
              },
              fit: BoxFit.contain,
            ),
          ),
        ),
        Positioned(
          top: 16,
          right: 16,
          child: Row(
            children: [
              IconButton(
                icon: const Icon(Icons.refresh),
                color: Colors.white,
                onPressed: _refreshImageToken,
                tooltip: '刷新',
              ),
              IconButton(
                icon: Icon(
                  _useDirectImage ? Icons.fullscreen : Icons.fullscreen_exit,
                ),
                color: Colors.white,
                onPressed: _toggleImageMode,
                tooltip: _useDirectImage ? '进入全屏模式' : '退出全屏模式',
              ),
              if (_currentUrl != null)
                IconButton(
                  icon: const Icon(Icons.download),
                  color: Colors.white,
                  onPressed: () => _downloadImage(context),
                  tooltip: '下载',
                ),
            ],
          ),
        ),
      ],
    );
  }

  /// 构建 PhotoView 图片预览
  Widget _buildPhotoViewGallery(BuildContext context) {
    return Stack(
      children: [
        PhotoViewGallery.builder(
          itemCount: 1,
          builder: (context, index) {
            return PhotoViewGalleryPageOptions(
              imageProvider: MinioImageProvider(
                _currentUrl!,
                headers: {'Accept': 'image/jpeg,image/png,image/*,*/*;q=0.8'},
              ),
              minScale: PhotoViewComputedScale.contained,
              maxScale: PhotoViewComputedScale.covered * 2,
              initialScale: PhotoViewComputedScale.contained,
              heroAttributes: PhotoViewHeroAttributes(tag: widget.fileId),
            );
          },
          loadingBuilder:
              (context, event) => Center(
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    CircularProgressIndicator(
                      value:
                          event?.expectedTotalBytes != null
                              ? event!.cumulativeBytesLoaded /
                                  event.expectedTotalBytes!
                              : null,
                    ),
                    const SizedBox(height: 16),
                    if (event?.expectedTotalBytes != null)
                      Text(
                        '加载中: ${((event!.cumulativeBytesLoaded / event.expectedTotalBytes!) * 100).toStringAsFixed(1)}%',
                      ),
                  ],
                ),
              ),
          backgroundDecoration: const BoxDecoration(color: Colors.black),
          pageController: PageController(),
          enableRotation: true,
          scrollPhysics: const BouncingScrollPhysics(),
        ),
        Positioned(
          top: 16,
          right: 16,
          child: Row(
            children: [
              IconButton(
                icon: const Icon(Icons.refresh),
                color: Colors.white,
                onPressed: _refreshImageToken,
                tooltip: '刷新',
              ),
              IconButton(
                icon: Icon(
                  _useDirectImage ? Icons.fullscreen : Icons.fullscreen_exit,
                ),
                color: Colors.white,
                onPressed: _toggleImageMode,
                tooltip: _useDirectImage ? '进入全屏模式' : '退出全屏模式',
              ),
              if (_currentUrl != null)
                IconButton(
                  icon: const Icon(Icons.download),
                  color: Colors.white,
                  onPressed: () => _downloadImage(context),
                  tooltip: '下载',
                ),
            ],
          ),
        ),
      ],
    );
  }

  void _downloadImage(BuildContext context) {
    // 实现下载图片的逻辑
  }

  /// 格式化字节大小
  String _formatBytes(int bytes) {
    if (bytes < 1024) return '$bytes B';
    if (bytes < 1024 * 1024) return '${(bytes / 1024).toStringAsFixed(1)} KB';
    if (bytes < 1024 * 1024 * 1024) {
      return '${(bytes / (1024 * 1024)).toStringAsFixed(1)} MB';
    }
    return '${(bytes / (1024 * 1024 * 1024)).toStringAsFixed(1)} GB';
  }

  /// 获取用户友好的错误消息
  String _getErrorDisplayMessage(String error) {
    // 处理超时相关错误
    if (error.contains('连接服务器超时')) {
      return '无法连接到服务器，请检查网络连接是否正常';
    }
    if (error.contains('发送请求超时')) {
      return '发送请求超时，请检查网络连接是否稳定';
    }
    if (error.contains('接收数据超时')) {
      return '图片加载超时，可能是因为：\n1. 图片文件较大\n2. 网络连接不稳定\n请检查网络后重试';
    }
    if (error.contains('网络连接错误')) {
      return '网络连接异常，请检查：\n1. 网络是否正常连接\n2. 是否可以访问服务器\n3. 网络是否被限制';
    }

    // 处理授权相关错误
    if (error.contains('403') || error.contains('访问被拒绝')) {
      return '图片访问授权已过期，请点击"刷新授权"按钮重试';
    }
    if (error.contains('404')) {
      return '图片不存在或已被删除';
    }

    // 处理图片格式错误
    if (error.contains('无效的图片格式')) {
      return '图片格式不正确或已损坏';
    }
    if (error.contains('无效的图片数据')) {
      return '图片数据无效，可能是文件已损坏';
    }

    // 处理其他网络错误
    if (error.contains('网络错误')) {
      return '网络请求失败，请检查网络连接后重试';
    }

    // 如果是其他错误，限制显示长度
    if (error.length > 100) {
      return '${error.substring(0, 100)}...';
    }
    return error;
  }

  /// 构建错误显示组件
  Widget _buildErrorWidget(BuildContext context) {
    final errorMessage = _getErrorDisplayMessage(_errorMessage ?? '未知错误');
    final bool isNetworkError =
        errorMessage.contains('网络') ||
        errorMessage.contains('超时') ||
        errorMessage.contains('连接');

    return Center(
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          Icon(
            isNetworkError ? Icons.wifi_off : Icons.broken_image,
            size: 64,
            color: Colors.grey[400],
          ),
          const SizedBox(height: 16),
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 32.0),
            child: Text(
              isNetworkError ? '网络连接问题' : '图片加载失败',
              style: TextStyle(
                color: Colors.red[300],
                fontSize: 16,
                fontWeight: FontWeight.bold,
              ),
              textAlign: TextAlign.center,
            ),
          ),
          const SizedBox(height: 8),
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 32.0),
            child: Text(
              errorMessage,
              style: TextStyle(color: Colors.grey[600]),
              textAlign: TextAlign.center,
            ),
          ),
          if (_currentUrl != null && !isNetworkError) ...[
            const SizedBox(height: 8),
            Padding(
              padding: const EdgeInsets.symmetric(horizontal: 32.0),
              child: Text(
                'URL: $_currentUrl',
                style: const TextStyle(fontSize: 10, color: Colors.grey),
                textAlign: TextAlign.center,
              ),
            ),
          ],
          const SizedBox(height: 24),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              ElevatedButton.icon(
                onPressed:
                    isNetworkError
                        ? _checkImageAvailability
                        : _refreshImageToken,
                icon: Icon(isNetworkError ? Icons.refresh : Icons.vpn_key),
                label: Text(isNetworkError ? '重试' : '刷新授权'),
                style: ElevatedButton.styleFrom(
                  backgroundColor: Theme.of(context).primaryColor,
                  foregroundColor: Colors.white,
                ),
              ),
              const SizedBox(width: 16),
              if (_currentUrl != null && !isNetworkError)
                OutlinedButton.icon(
                  onPressed: () async {
                    final url = Uri.parse(_currentUrl!);
                    if (await canLaunchUrl(url)) {
                      await launchUrl(
                        url,
                        mode: LaunchMode.externalApplication,
                      );
                    }
                  },
                  icon: const Icon(Icons.open_in_browser),
                  label: const Text('在浏览器中打开'),
                ),
            ],
          ),
        ],
      ),
    );
  }
}
